//-< CodeGenerator.cs >----------------------------------------------*--------*
// JSQL                       Version 1.04       (c) 1999  GARRET    *     ?  *
// (Java SQL)                                                        *   /\|  *
//                                                                   *  /  \  *
//                          Created:     23-Mar-2009  K.A. Knizhnik  * / [] \ *
//                          Last update: 23-Mar-2009  K.A. Knizhnik  * GARRET *
//-------------------------------------------------------------------*--------*
// JQSL query generator
//-------------------------------------------------------------------*--------*

namespace Perst
{    
    using System;

    /// <summary>
    /// Class representing abstract syntax tree generated by query code generator
    /// </summary>
    public interface Code {}
    
    /// <summary>
    /// Code generator for JSQL queries.
    /// </summary>
    public interface CodeGenerator
    {
        /// <summary>
        /// Set query predicate code
        /// </summary>
        /// <param name="code">AST constructed using CodeGenerator methods</param>
        void Predicate(Code code);
                                                    
        /// <summary>
        /// Literal constant 
        /// </summary>
        Code Literal(Object value);
        
        /// <summary>
        /// List of alternatives for IN operator 
        /// </summary>
        Code List(params Code[] values);
    
        /// <summary>
        /// Query parameter
        /// </summary>
        /// <param name="n">parameter index (0 based)</param>
        /// <param name="type">parameter type</param>
        Code Parameter(int n, Type type);
    
        /// <summary>
        /// Get self field
        /// </summary>
        /// <param name="name">field name</param>
        Code Field(String name);
    
        /// <summary>
        /// Get field
        /// </summary>
        /// <param name="baseExpr">target object</param>
        /// <param name="name">field name</param>
        Code Field(Code baseExpr, String name);
    
        /// <summary>
        /// Invoke method
        /// </summary>
        /// <param name="baseExpr">invocation  target</param>
        /// <param name="name">method name</param>
        /// <param name="arguments">method arguments</param>
        Code Invoke(Code baseExpr, String name, params Code[] arguments);
    
        /// <summary>
        /// Invoke self method
        /// </summary>
        /// <param name="name">method name</param>
        /// <param name="arguments">method arguments</param>
        Code Invoke(String name, params Code[] arguments);
    
        Code And(Code left, Code right);
        Code Or(Code left, Code right);
    
        Code Add(Code left, Code right);
        Code Sub(Code left, Code right);
        Code Mul(Code left, Code right);
        Code Div(Code left, Code right);
        Code Pow(Code left, Code right);
    
        Code Eq(Code left, Code right);
        Code Ge(Code left, Code right);
        Code Gt(Code left, Code right);
        Code Lt(Code left, Code right);
        Code Le(Code left, Code right);
        Code Ne(Code left, Code right);
    
        Code Neg(Code expr);
        Code Abs(Code expr);
        Code Not(Code expr);
    
        Code Between(Code expr, Code low, Code high);
        Code Like(Code expr, Code pattern, Code esc);
        Code Like(Code expr, Code pattern);
        Code In(Code expr, Code set);
    
        Code Sin(Code expr);
        Code Cos(Code expr);
        Code Tan(Code expr);
        Code Asin(Code expr);
        Code Acos(Code expr);
        Code Atan(Code expr);
        Code Sqrt(Code expr);
        Code Exp(Code expr);
        Code Log(Code expr);
        Code Ceil(Code expr);
        Code Floor(Code expr);
    
        /// <summary>
        /// Convert string to lower case
        /// </summary>
        Code Lower(Code expr);
    
        /// <summary>
        /// Convert string to upper case
        /// </summary>
        Code Upper(Code expr);
    
        /// <summary>
        /// Get array length
        /// </summary>
        Code Length(Code expr);
    
        /// <summary>
        /// Get array element
        /// </summary>
        Code GetAt(Code array, Code index);
    
        /// <summary>
        /// Convert real to integer
        /// </summary>
        Code Integer(Code expr);
    
        /// <summary>
        /// Convert integer to real
        /// </summary>
        Code Real(Code expr);
    
        /// <summary>
        /// Convert integer/real/date to string
        /// </summary>
        Code String(Code expr);
    
        /// <summary>
        /// Add order by clause. It is possible to invoke this method several times - in this case
        /// result will be sorted by all specified fields in the correspondent order
        /// </summary>
        /// <param name="name">field name by which sort should be performed</param>
        /// <param name="ascent">true for ascent order, false for descent order</param>
        void OrderBy(String name, bool ascent);
    
        /// <summary>
        /// Add order by clause. It is possible to invoke this method several times - in this case
        /// result will be sorted by all specified fields in the correspondent order
        /// </summary>
        /// <param name="name">field name by which sort should be performed</param>
        void OrderBy(String name);
    }
}